from django.db.models import F
from django.shortcuts import render
from rest_framework.decorators import action
from rest_framework.mixins import ListModelMixin
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.status import HTTP_404_NOT_FOUND
from rest_framework.viewsets import GenericViewSet, ModelViewSet
from rest_framework import viewsets
from community.models import Label, Article, Comment
from community.paginations import ArticleLimitOffsetPagination
from community.serializers import LabelSerializer, ArticleSerializer, CommentSerializer, SonCommentSerializer


# Create your views here.

# 127.0.0.1:8000/community/labels
# 标签视图
# 放到 admin 后台管理  不同对外 增删改  查询的接口
class LabelViewSet(GenericViewSet, ListModelMixin):
    queryset = Label.objects.all()
    serializer_class = LabelSerializer
    # 权限  登录权限  能够选择标签的 是登录的用户
    permission_classes = [IsAuthenticated]


# 文章视图
class ArticleViewSet(ModelViewSet):
    # 文章的查询集
    queryset = Article.objects.filter(is_delete=False)
    serializer_class = ArticleSerializer
    permission_classes = [IsAuthenticated]
    # 定义使用的分页器
    pagination_class = ArticleLimitOffsetPagination

    # 重写查询集
    def get_queryset(self):
        # 查看所有的文章的时候 或者 查看单一文章的时候
        if self.action in ['list', 'retrieve']:
            return self.queryset.filter(status=1)
        else:
            return self.queryset

    def get_serializer_class(self):
        # 如果激活的是comment 使用的序列化器==》评论的序列化器
        if self.action == 'comment':
            return CommentSerializer
        else:
            return self.serializer_class

    # 创建文章的时候
    # 创建文章的功能是ok的
    # 重写create方法
    def create(self, request, *args, **kwargs):
        # 当前的登录用户id  request.user.id  3    2
        request.POST._mutable = True  # 允许修改post提交的数据
        request.data['user'] = request.user.id
        # 继续使用create方法 来创建文章
        return ModelViewSet.create(self, request, *args, **kwargs)

    # 重写一下retrieve 方法
    # retrieve 查询单一数据的方法
    # 修改和查询  继承父类的ModelViewSet.retrieve 方法

    def retrieve(self, request, *args, **kwargs):
        # kwargs ["pk"] =  文章的id

        self.get_queryset().filter(id=kwargs['pk']).update(page_view=F("page_view") + 1)
        return ModelViewSet.retrieve(self, request, *args, **kwargs)

    # 获取指定文章所有的一级评论  #文章的id
    # 127.0.0.1:8000/community/article/文章id/comment
    @action(methods=['get'], detail=True)
    def comment(self, request, pk):
        try:
            article = self.get_queryset().get(id=pk)
        except Article.DoesNotExist:
            return Response(status=HTTP_404_NOT_FOUND)

        # 通过文章关联查询得到评论的数据
        comments = article.comment_set.filter(parent_comment__isnull=True)

        # 添加分页器
        comment_page = self.paginate_queryset(comments)

        # 需要用到评论的序列化器  序列化
        serialzier = self.get_serializer(comment_page, many=True)
        return self.get_paginated_response(serialzier.data)


# 评论的视图
class CommentViewSet(ModelViewSet):
    # 查询集
    queryset = Comment.objects.filter(is_delete=False, article__is_delete=False, article__status=1)
    # 序列化器
    serializer_class = CommentSerializer
    # 权限
    permission_classes = [IsAuthenticated]

    # 定义使用的分页器
    pagination_class = ArticleLimitOffsetPagination

    # 重写序列器方法
    def get_serializer_class(self):
        # 如果激活的是comment 使用的序列化器==》评论的序列化器
        if self.action == 'retrieve':
            return SonCommentSerializer
        else:
            return self.serializer_class

    # 对于发布评论 绑定为当前登录的用户
    def create(self, request, *args, **kwargs):
        # 当前的登录用户id  request.user.id  3    2
        request.POST._mutable = True  # 允许修改post提交的数据
        request.data['user'] = request.user.id
        # 继续使用create方法 来创建文章
        return ModelViewSet.create(self, request, *args, **kwargs)

    # 因为前面的父级评论 已经是展示再文章里面的
    # 子级评论只需要得到父级评论的id
    def retrieve(self, request, *args, **kwargs):
        try:
            comment = self.get_queryset().get(id=kwargs['pk'])
        except Comment.DoesNotExist:
            return Response(status=HTTP_404_NOT_FOUND)
        # comment 父级评论
        comments = comment.parent_comment_set.all()

        comment_page = self.paginate_queryset(comments)

        # 需要用到评论的序列化器  序列化
        serialzier = self.get_serializer(comment_page, many=True)
        return self.get_paginated_response(serialzier.data)

        # 127.0.0.1:8000/community/comment/2
